/*
Copyright (c) 2025 HeZongLun
NahidaProject is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan
PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/

#pragma once

#ifdef _WIN32
#define ExportSymbol  __declspec(dllexport)
#else
#define ExportSymbol
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <stdexcept>

namespace NahidaProject {
	class ExportSymbol Time {
	private:
		int hour;
		int minute;
		int second;

		bool IsValid(int h, int m, int s) const;
		void Normalize();

	public:
		Time() : hour(0), minute(0), second(0) {

		}

		Time(int h, int m, int s) {
			if (!IsValid(h, m, s)) {
				throw std::invalid_argument("Invalid time values");
			}
			hour = h;
			minute = m;
			second = s;
		}

		Time(int seconds) {
			if (seconds < 0) {
				seconds = 0;
			}
			hour = (seconds / 3600) % 24;
			minute = (seconds % 3600) / 60;
			second = seconds % 60;
		}

		Time(const Time& other) : hour(other.hour), minute(other.minute), second(other.second) {

		}

		Time& operator=(const Time& other);
		int GetHour() const;
		int GetMinute() const;
		int GetSecond() const;
		void SetHour(int h);
		void SetMinute(int m);
		void SetSecond(int s);
		void SetTime(int h, int m, int s);
		int ToSeconds() const;
		void AddHours(int hours);
		void AddMinutes(int minutes);
		void AddSeconds(int seconds);
		void AddTime(int h, int m, int s);
		void SubtractHours(int hours);
		void SubtractMinutes(int minutes);
		void SubtractSeconds(int seconds);
		void SubtractTime(int h, int m, int s);
		int Difference(const Time& other) const;
		std::string ToString() const;
		std::string To12HourFormat() const;
		Time operator+(const Time& other) const;
		Time operator-(const Time& other) const;
		Time& operator+=(const Time& other);
		Time& operator-=(const Time& other);
		bool operator==(const Time& other) const;
		bool operator!=(const Time& other) const;
		bool operator<(const Time& other) const;
		bool operator<=(const Time& other) const;
		bool operator>(const Time& other) const;
		bool operator>=(const Time& other) const;
		Time& operator++();
		Time& operator--();
		Time operator++(int);
		Time operator--(int);
		static Time Parse(const std::string& timeStr);
		static Time Now();
	};
}
